package com.g0dkar.leet.util.ognl.typeConversion;

import java.lang.reflect.Member;
import java.util.Map;

import ognl.DefaultTypeConverter;
import ognl.TypeConverter;

import com.g0dkar.leet.log.Log;

public class LeetOGNLTypeConverter implements TypeConverter {
	private static DefaultTypeConverter DEFAULT_TYPE_CONVERTER;
	
	static {
		DEFAULT_TYPE_CONVERTER = new DefaultTypeConverter();
	}
	
	public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType) {
		Object result = null;
		
		try {
			if (value.getClass().equals(String.class)) {
				com.g0dkar.leet.util.ognl.typeConversion.TypeConverter converter = TypeConverterManager.getConverterFor(toType);
				
				if (converter != null) {
					result = converter.fromString(value.toString(), toType, null);
				}
				else {
					Log.debug("No TypeConverter found for {} -> String conversion. Using {} instead", value.getClass().getName(), DEFAULT_TYPE_CONVERTER.getClass().getName());
				}
			}
			else if (toType.equals(String.class)) {
				com.g0dkar.leet.util.ognl.typeConversion.TypeConverter converter = TypeConverterManager.getConverterFor(value.getClass());
				
				if (converter != null) {
					result = converter.toString(value, null);
				}
				else {
					Log.debug("No TypeConverter found for String -> {} conversion. Using {} instead", value.getClass().getName(), DEFAULT_TYPE_CONVERTER.getClass().getName());
				}
			}
		} catch (Exception e) {
			Log.warn("Could not convert {} into {} using a {} type converter, using {} instead", value.getClass().getName(), toType.getName(), DEFAULT_TYPE_CONVERTER.getClass().getName());
			result = null;
		}
		
		if (result == null) {
			result = DEFAULT_TYPE_CONVERTER.convertValue(context, target, member, propertyName, value, toType);
		}
		
		return result;
	}
	
}
